# Simulation enviroment
import os

import ground
import staticObject
import robot

class World:
	def __init__(self,display):
		# display
		self.display = display

		# ground
		self.ground = ground.Ground(display)

		# static objects: obs
		self.n_obs=0
		self.obs=[]
		self.createObs()

		# moving objects: robot
		self.robot = robot.Robot(display)

		# x of the screen boundary
		self.show_x = self.robot.x - 11

	def createObs(self,n_obs=2):
		self.WIDTH = 10
		self.HEIGHT = 15
		self.MIN_DISTANCE = 150

		self.n_obs=n_obs
		self.obs.clear()

		last_obs_x = 20 # first obs pos
		for o in range(self.n_obs):
			r = int.from_bytes(os.urandom(1),'big')
			current_x = last_obs_x + self.MIN_DISTANCE + r%10
			current_y = self.ground.ground_level - int(self.HEIGHT/2) + r%5
			self.obs.append(staticObject.StaticObject(self.display,current_x, current_y, self.WIDTH + r%30, self.HEIGHT, o))
			last_obs_x = current_x

	def reset(self):
		# reset ground
		self.ground.reset()

		# delete old obs, create new obs
		self.createObs()

		# reset robot
		self.robot.reset()

	def update(self):
		# update robot
		self.robot.update()

		# update x of boundary
		self.show_x = self.robot.x - 11

		# update groud line
		self.ground.update(self.show_x)

		# update obs
		for o in range(self.n_obs):
			self.obs[o].update(self.show_x)

		# dectection collision
		self.collision()

		# update distance sensor
		self.measure()

		# # robot desicion
		# self.robot.think()

	def show(self):
		self.ground.show(self.show_x)

		for o in range(self.n_obs):
			self.obs[o].show(self.show_x)

		self.robot.show(self.show_x)

	def collision(self):
		self.robot.collision = -1
		for o in range(self.n_obs):
			if(( abs(self.robot.x - self.obs[o].x) < (self.robot.width//2 + self.obs[o].width//2)) and \
					( abs(self.robot.y - self.obs[o].y) < (self.robot.height//2 + self.obs[o].height//2))):
				self.robot.collision = o
				self.robot.n_collisions += 1
				return True
		return False

	def measure(self):
		self.robot.obs = -1
		self.robot.distance = 10.0
		for o in range(self.n_obs):
			diff = (self.obs[o].x - self.robot.x)/100
			if(diff > 0 and diff < self.robot.distance):
				self.robot.distance = diff
				self.robot.obs_width = self.obs[o].width / 100
				self.robot.obs = o
		# print(self.robot.obs, self.robot.distance)
		return self.robot.distance, self.robot.obs_width
